package cn.wolfcode.p2p.hosting.util;

import cn.wolfcode.p2p.base.exception.CustomException;
import cn.wolfcode.p2p.util.Assert;
import com.alibaba.fastjson.JSON;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * 托管接入工具
 */
public class HostingUtil {

    public static final String SIGN_TYPE = "RSA";
    public static final String INPUT_CHARSET = "UTF-8";
    public static final String SIGN_VERSION = "1.0";
    public static final String ENCRYPT_VERSION = "1.0";
    //托管账户标识前缀
    public static final String ACCOUNT_PREFIX = "wolfcode_";
    //签名私钥
    public static final String SIGN_KEY_PRIVATE = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJJqxunyHgxWN2aTSZp2jAYTOwGDeuS/Dkolk3g6/svnhVYAYn8iyjJ5Fo6YQcCz3F1+3YGjq1I1mIKRi3GaRoN3859vuCdo9nWFowF7BgepNSoGZY7uyYVc6EO3+TdeAlvdCceEng/a3hRoDcjLbsXdV9KwSfoCzdoRegy+yGf1AgMBAAECgYAHaRoaOyPkMfTp3yiJhdh+cji5UeNFcpoRjKdTHYFJ5rTr7mcN0j/zoAdRPkmNrEzJ+qLRbew84/ONIDqzjEBnUMRyWbq9rCr/yodld6uY8yQvXONGukv0mDArnsB+0HswkZ4oIMdHyw8EiCjcO+nBE63nc3ejw9XjBjwuUP/PwQJBAPtwxlwu9ORvn5LInQx/xEw6LWRn1kHuzU2V8QPuaZ1u/0MJ0Z1MqtEdWd4cUkox5etxpjAK8Ok7XUgfwcPdEjECQQCVEnep8vpDBxvokuz0bHARzGjUuZpMysBiTmbaUEwsAeCDj+rfQohISCF7GEDOargqKdlZ9XeBU5kZ/PEhf50FAkEA4r9/0o/x/rN/ByLtJeFux4NLfhl6Cblt4YLPd8kf6362qeEH7D/AZ5Z9faSyvQAkpN+3i+nB+cK0S59/4L7TcQJAeedtNew93Xw9xVYJMeRPTS7Ed1kEJlITOxD0KQlLER3D1LJnFoXY3osl3fy6WlKJIemxFVCXlomfhNIE+ijaZQJBANIxZSIC1qD9CA/RzPgxvpu0tjBN0u8Gak4lnUKtmBoBAyILoKkJ4ctElwqCpG4SAMLz6keWUYTUxXjrsR9sXiE=";

    //会员网关
    public static final String URL_MGS = "http://localhost:1111/mgs/gateway.do";

    //回签公钥
    private static final String SIGN_KEY_PUBLIC = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCSasbp8h4MVjdmk0madowGEzsBg3rkvw5KJZN4Ov7L54VWAGJ/IsoyeRaOmEHAs9xdft2Bo6tSNZiCkYtxmkaDd/Ofb7gnaPZ1haMBewYHqTUqBmWO7smFXOhDt/k3XgJb3QnHhJ4P2t4UaA3Iy27F3VfSsEn6As3aEXoMvshn9QIDAQAB";

    //收单网关
    public static final String URL_MAS = "http://localhost:1111/mas/gateway.do";

    //基本参数
    public static Map<String, String> getBaseParamMap() {
        Map<String, String> map = new HashMap<>();
        map.put("version", "1.0");
        map.put("request_time", getRequestTimeString());
        map.put("partner_id", "200004595271");
        map.put("_input_charset", INPUT_CHARSET);
        map.put("sign_type", SIGN_TYPE);
        map.put("sign_version", SIGN_VERSION);
        map.put("encrypt_version", ENCRYPT_VERSION);
        return map;
    }

    //创建请求时间参数
    public static String getRequestTimeString() {
        return new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
    }

    //请求签名
    public static String sign(Map<String, String> baseParamMap) {
        try {
            //1.准备签名字符串, (基本参数,不需要编码,要过滤)
            String signLinkString = Tools.createLinkString(baseParamMap, false, true);

            //2.执行签名(签名字符串,签名类型,私钥,编码格式)
            return SignUtil.sign(signLinkString, SIGN_TYPE, SIGN_KEY_PRIVATE, INPUT_CHARSET);

        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomException("签名失败");
        }

    }

    //重载sendRequest方法
    public static String sendRequest(Map<String, String> baseParamMap, String url) {

        return sendRequest(baseParamMap, url, false);
    }

    //发送请求
    public static String sendRequest(Map<String, String> baseParamMap, String url, Boolean isHtml) {
        try {

            //准备签名
            String signString = HostingUtil.sign(baseParamMap);

            //把签名设置给基本参数
            baseParamMap.put("sign", signString);


            //1.准备拼接请求参数, 带有签名的参数, 需要编码,不需过滤
            String requestLinkString = Tools.createLinkString(baseParamMap, true, false);

            //2.提交POST请求,
            String resultString = CallServiceUtil.sendPost(url, requestLinkString);

            //如果是html,直接返回结果
            if (isHtml) {
                return resultString;
            }

            //3.获取结果,url解码
            resultString = URLDecoder.decode(resultString, INPUT_CHARSET);

            //4.回签检查
            //把响应结果字符串转换为map
            Map<String, String> resultParamMap = JSON.parseObject(resultString, Map.class);
            if (resultParamMap.get("response_code").equals("APPLY_SUCCESS")) {
                checkSign(resultParamMap);
            }
            return null;

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            throw new CustomException("托管请求失败");
        }


    }

    //回签
    public static boolean checkSign(Map<String, String> resultParamMap) {
        try {
            //准备回签的字符串
            String stringLinkString = Tools.createLinkString(resultParamMap, false, true);

            //网关返回的签名密文
            String sign = resultParamMap.put("sign", stringLinkString);
            //执行签名
            boolean success = SignUtil.Check_sign(stringLinkString, sign, SIGN_TYPE, SIGN_KEY_PUBLIC, INPUT_CHARSET);
            Assert.isFalse(!success, "检查签名失败");
            return success;

        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomException("检查签名失败");
        }


    }

    /**
     * 把request对象转化成map
     *
     * @param request
     * @return
     */
    public static Map<String, String> requestToMap(HttpServletRequest request) {
        Enumeration<String> names = request.getParameterNames();
        Map<String, String> map = new HashMap<>();
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            String value = request.getParameter(name);
            map.put(name, value);
        }
        return map;
    }
}
